package com.yiyihealth.cherriesadmin.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.yiyihealth.cherriesadmin.core.http.HttpResult;
import com.yiyihealth.cherriesadmin.core.web.BaseController;
import com.yiyihealth.cherriesadmin.core.webservice.MainServiceImplPortType;
import com.yiyihealth.cherriesadmin.core.webservice.MainServiceImplPortTypeService;
import com.yiyihealth.cherriesadmin.model.*;
import com.yiyihealth.cherriesadmin.model.jkt.JktFunc10003;
import com.yiyihealth.cherriesadmin.model.wrapper.PubDoctorWrapper;
import com.yiyihealth.cherriesadmin.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 医疗机构与人员信息关系表
 * (PubDoctor)表控制层
 *
 * @author chen
 * @since 2020-09-14 20:03:50
 */
@Api(tags = "医生管理类")
@RestController
@RequestMapping("pubDoctor")
public class PubDoctorController extends BaseController<PubDoctor, PubDoctorWrapper, Long> {
    /**
     * 服务对象
     */
    @Resource
    private OrdSchedulingTemplateService ordSchedulingTemplateService;
    @Resource
    private OrdSchedulingService schedulingService;
    @Resource
    private PubDoctorService pubDoctorService;
    @Resource
    private PubHospitalService hospitalService;
    @Resource
    private PubDictionaryService dictionaryService;
    @Resource
    private PubDepartmentsService departmentsService;
    @Autowired
    private RedisTemplate<Object, Object> redisCacheTemplate;

    @Override
    @InitBinder()
    public void initBinder(WebDataBinder binder) {
        super.setBaseService(pubDoctorService);
    }

    @GetMapping("/selectListByDepId")
    @ResponseBody
    public HttpResult selectListByDepId(@RequestParam Long depId, @RequestParam Long patId) throws Exception {
        return HttpResult.success(pubDoctorService.selectListByDepId(depId, "0", patId));
    }

    @PostMapping("/createDoctor")
    @ResponseBody
    public HttpResult create(@RequestBody PubDoctor record, HttpServletRequest request) throws Exception {
        String imgUrl = (String) request.getSession().getAttribute("imgUrl");
        if (StrUtil.isBlank(record.getImageUrl())){
            record.setImageUrl(imgUrl);
        }
        return HttpResult.success(pubDoctorService.insert(record));
    }

    @PostMapping("/updateDoctor")
    @ResponseBody
    public HttpResult update(@RequestBody PubDoctor record, HttpServletRequest request) throws Exception {
        String imgUrl = (String) request.getSession().getAttribute("imgUrl");
        if (StrUtil.isBlank(record.getImageUrl())){
            record.setImageUrl(imgUrl);
        }
        PubDoctor doctor = pubDoctorService.updateByPrimaryKeySelective(record);
        Map<String, Object> map = new HashMap<String, Object>(8);
        map.put("doctorId", doctor.getId());
        List<OrdSchedulingTemplate> schedulingTemplateList = ordSchedulingTemplateService.selectList(map);
        for (OrdSchedulingTemplate ordSchedulingTemplate:schedulingTemplateList){
            ordSchedulingTemplate.setDoctorPracticeScope(record.getDoctorPracticeScope());
            ordSchedulingTemplateService.updateByPrimaryKeySelective(ordSchedulingTemplate);
            map.clear();
            map.put("templateId", ordSchedulingTemplate.getId());
            List<OrdScheduling> ordSchedulingList = schedulingService.selectList(map);
            for (OrdScheduling ordScheduling:ordSchedulingList){
                ordScheduling.setDoctorPracticeScope(record.getDoctorPracticeScope());
                schedulingService.updateByPrimaryKeySelective(ordScheduling);
            }
        }

        return HttpResult.success(doctor);
    }

    /**
     * 上传医生信息到预约挂号平台
     *
     * @return
     * @url /pub/staff_hosptal/upload
     */
    @PostMapping("/deleteImage")
    @ResponseBody
    public HttpResult deleteImage(@RequestBody PubDoctor record, HttpServletRequest request) throws Exception {
        record.setImageUrl("");
        pubDoctorService.updateByPrimaryKey(record);
        request.getSession().setAttribute("imgUrl", "");
        return HttpResult.success("删除医生头像成功！");
    }


    /**
     * 医生图片上传
     *
     * @param file
     * @param request
     * @return
     */
    @ApiOperation(value = "医生图片上传")
    @ApiResponse(code = 400, message = "参数没有填好", response = String.class)
    @ApiImplicitParam(name = "file", value = "file", required = true, type = "MultipartFile")
    @PostMapping(value = "imageUpload")
    @ResponseBody
    public String imageUpload(@RequestParam MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) {
            return "文件为空";
        }
        // 获取文件名
        String fileName = file.getOriginalFilename();
        //获取文件类型，以最后一个`.`为标识
        String type = fileName.substring(fileName.lastIndexOf(".") + 1);
        fileName = IdUtil.randomUUID() + "." + type;
        // 获取服务器所在地址
        String path = request.getServletContext().getRealPath("/");

        //创建文件路径
        File dest = null;
        if (SystemUtil.getOsInfo().isLinux()) {
            dest = new File("/home/img/" + fileName);
        } else {
            dest = new File("D:/test/" + fileName);
        }
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest);
            String url = "static/" + fileName;
            request.getSession().setAttribute("imgUrl", url);
            return url;
        } catch (Exception e) {
            return "上传失败";
        }
    }

    /**
     * 上传医生信息到预约挂号平台
     *
     * @return
     * @url /pub/staff_hosptal/upload
     */
    @PostMapping("/uploadByID")
    @ResponseBody
    public HttpResult uploadByID(@RequestParam Long id) throws Exception {
        PubDoctor doctor = pubDoctorService.selectByPrimaryKey(id);
        try {
            upload12580(doctor);
        }catch (Exception e){
            return HttpResult.failure(e.getMessage());
        }
        return HttpResult.success("上传医生信息到预约挂号平台！");
    }
    /**
     * 上传医生信息到预约挂号平台
     *
     * @return
     * @url /pub/staff_hosptal/upload
     */
    @PostMapping("/upload")
    @ResponseBody
    public HttpResult upload(@RequestParam Long hospitalId) throws Exception {

        Map<String, Object> map = new HashMap<>();
        if (!hospitalId.toString().equals("0")) {
            map.put("hospitalId", hospitalId);
        }
        List<PubDoctor> doctorList = pubDoctorService.selectList(map);
        for (PubDoctor doctor : doctorList) {
                try {
                    PubDepartments departments = departmentsService.selectByPrimaryKey(doctor.getDepId());
                    if (Optional.ofNullable(departments).isPresent()){
                        upload12580(doctor);
                    }
                }catch (Exception e){
                    return HttpResult.failure(e.getMessage());
                }
        }
        return HttpResult.success("上传医生信息到预约挂号平台！");
    }

    private void upload12580(PubDoctor doctor) throws Exception {
        try {
            MainServiceImplPortType service = new MainServiceImplPortTypeService().getMainServiceImplPortTypePort();
            if (doctor.getDoctorName().equals("余鉴仓")){
                System.out.println(doctor);
            }
            PubHospital hospital = hospitalService.selectByPrimaryKey(doctor.getHospitalId());
            Document document = DocumentHelper.createDocument();
            Element root = document.addElement("data");
            Element funcode = root.addElement("funcode");
            funcode.setText("200103");

            //1. 医院编号 orgid 32 N 单医院接入传空，地 市平台接入传医院 在地市平台的编号
            Element orgid = root.addElement("orgid");
            orgid.setText(hospital.getHosMarkCode());

            //2. 医生编号 docid 20 N 医生在医院内的唯 一标识, 精确查询
            Element docid = root.addElement("docid");
            docid.setText(doctor.getDoctorCode());

            //3. 医生姓名 docname 20 N
            Element docname = root.addElement("docname");
            docname.setText(doctor.getDoctorName());

            //4. 医生性别 docsex 2 N 男或女
            Element docsex = root.addElement("docsex");
            docsex.setText(doctor.getDoctorSex().equals("男") ? "1" : "2");

            //5. 科室编号 deptid 50 N 医生所属科室在医 院的唯一标识， 多 个以英文逗号(,)隔 开
            Element deptid = root.addElement("deptid");
            PubDepartments departments = departmentsService.selectByPrimaryKey(doctor.getDepId());
            if (!Optional.ofNullable(departments).isPresent()){
                throw new Exception("预约挂号：未找到对应科室信息" );
            }
            deptid.setText(departments.getDepInternalCode());

            //6. 医生职称 title 3 N 见专业技术职务代 码
            Element title = root.addElement("title");
            title.setText(dictionaryService.selectByPrimaryKey(doctor.getDoctorProfessional()).getDicCode());

            //7. 医生介绍 description 2000 Y
            Element description = root.addElement("description");
            description.setText(doctor.getDoctorSummary());

            //8. 擅长 goodat 4000 Y
            Element goodat = root.addElement("goodat");
            goodat.setText(doctor.getDoctorGoodat());

            //10. 医生状态 state 1 Y 0-有效 1-无效
            Element state = root.addElement("state");
            if (StrUtil.isBlank(doctor.getStatus())) {
                doctor.setStatus("0");
            }
            //只限自有平台显示医生信息
            if (doctor.getDoctorPracticeScope().equals("1")) {
                doctor.setStatus("1");
            }
            state.setText(doctor.getStatus());
            String strResult = "";

            System.out.println("HIS请求："+document.asXML());
            strResult = service.funMain(document.asXML());
            System.out.println("平台结果："+strResult);
            Document documentResult = DocumentHelper.parseText(strResult);
            //获取根节点
            Element rootElt = documentResult.getRootElement();
            //获取根节点名称
            String rootName = rootElt.getName();
            //获取子节点
            Element stateElt = rootElt.element("state");
            Element resultElt = rootElt.element("result");
            if (!stateElt.getTextTrim().equals("0")) {
                throw new Exception(resultElt.getTextTrim());
            }
        } catch (Exception e) {
            throw new Exception("预约挂号：" + doctor.getDoctorName() + e.getMessage());
        }
    }

    @RequestMapping("/extractHisData")
    @ResponseBody
    public HttpResult extractHisData() throws Exception {
        try {
            pubDoctorService.ExtractHisData();
            redisCacheTemplate.delete("options::0");
            redisCacheTemplate.delete("options::57170");
            redisCacheTemplate.delete("options::57171");
            redisCacheTemplate.delete("options::57172");
            schedulingService.selectListForOptions(0L);
            schedulingService.selectListForOptions(57170L);
            schedulingService.selectListForOptions(57171L);
            schedulingService.selectListForOptions(57172L);
        } catch (Exception e) {
            return HttpResult.failure(e.getMessage());
        }
        return HttpResult.success("抽取HIS医生信息成功！");
    }

    /**
     * 上传医生信息到预约挂号平台
     *
     * @return
     * @url /pub/staff_hosptal/upload
     */
    @ApiOperation(value = "健康通--医院医生信息上传")
    @PostMapping("/jktUpload")
    @ResponseBody
    public HttpResult jktUpload(@RequestParam Long hospitalId) throws Exception {
        try {
            pubDoctorService.jktUpload(hospitalId);
        }catch (Exception e){
            return HttpResult.failure(e.getMessage());
        }
        return HttpResult.success("上传医生信息到预约挂号平台！");
    }
}
